//---------------------------------------------------------------
//University of Central Florida
//Senior Design 2
//Dr. Richie
//Group 6: Devin King, Steve Johnson, John Blackburn, Anish Pant
//Substation Power Monitoring System
//---------------------------------------------------------------

#include <p18f4550.h>
#include <delays.h>
#include <stdlib.h>
#include <stdio.h>
#include <xlcd.h>
#include <adc.h>
#include <usart.h>
#include <string.h>


#pragma config FOSC = INTOSC_XT //Internal oscillator
#pragma config FCMEN = OFF		//Failsafe Clock Monitor
#pragma config IESO = OFF		//Internal External Oscillator Switchover
#pragma config PWRT = ON		//Power Up Timer
#pragma config BOR = OFF		//Brown Out Reset
#pragma config WDT = OFF		//Watchdog Timer
#pragma config MCLRE = OFF		//MCLR
#pragma config LVP = OFF		//Low Voltage Programming

void USART(void);

int i = 0, num, j = 0, h = 0;
int result1 = 0;
int result1A = 0;
int result2 = 0;
int result2A = 0;
float CTvoltage = 0;
float voltage = 0;
float power = 0;
float current = 0;
float currentRatio = 0;
char* data;
char buffer[20];
char c[4], word[4] = "1111", string;

unsigned int currentScale;
unsigned int powerScale;

unsigned int intCurrent = 0;
unsigned int iResult = 0;
char* CurrentString;
char* currentIntString;
char* relayString;
char* rrcurrent;
char* relayString;

//reg is the array for scada to read from
//reg[0] is status
//reg[5] is current
//reg[6] is power
unsigned int reg[10];
unsigned char* creg = reg;


void main( void )
{
	
	TRISDbits.TRISD0 = 0;
	TRISDbits.TRISD1 = 0;
	PORTDbits.RD1 = 0;
	PORTDbits.RD0 = 0;
	TRISDbits.TRISD2 = 1;

//	OSCCON = 0b01110000;    //8 MHz
	OSCCON = 0b01100000;	//4 MHz

//-----------------------------------------------------------------------
//Set up LCD and Output titles
//-----------------------------------------------------------------------

	OpenXLCD( FOUR_BIT & LINES_5X7 );	//Initialize LCD
	Delay10TCYx(100); 					// Delay for 50TCY

	while( BusyXLCD() );
	WriteCmdXLCD(CURSOR_OFF);
	WriteCmdXLCD(BLINK_OFF);
	
	while( BusyXLCD() );
	data = ("Working");
	putsXLCD(data);

	SetDDRamAddr(0x00);
	putrsXLCD("                ");
	SetDDRamAddr(0x40);
	putrsXLCD("                ");

//-----------------------------------------------------------------------
//Configure A/D Converter
//-----------------------------------------------------------------------

	OpenADC(ADC_FOSC_RC & 
			ADC_RIGHT_JUST & ADC_0_TAD, 
			ADC_CH1 & 
			ADC_INT_OFF & 
			ADC_VREFPLUS_VDD & 
			ADC_VREFMINUS_VSS,
			0b0110);


//-----------------------------------------------------------------------
//Configure USART
//-----------------------------------------------------------------------

	OpenUSART(USART_TX_INT_ON & 
			USART_RX_INT_ON & 
			USART_ASYNCH_MODE & 
			USART_EIGHT_BIT & 
			USART_CONT_RX & 
			USART_BRGH_HIGH, 25 );


    while(1)
	{

//-----------------------------------------------------------------------
//Display the Voltage and Current values to the LCD
//-----------------------------------------------------------------------

	for(i = 1; i<30; i++){ 

		USART();

		//Relay status if RD2 is high then relay is open, else closed.
		if (PORTDbits.RD2 == 1) {
			//reg is the reg for scada to read from
			reg[0] = 1; 
			SetDDRamAddr(0x47);
			putrsXLCD("Open  ");
		}
		else {
			reg[0] = 0;
			SetDDRamAddr(0x47);
			putrsXLCD("Closed");
		}

		SetDDRamAddr(0x00);					//Set cursor to first line
		putrsXLCD("Current:");
		SetDDRamAddr(0x40);					//Set cursor to second line
		putrsXLCD("Relay:");

		//Read in Data 
		SetChanADC(ADC_CH1);
		Delay10TCYx(600); 			// Delay for 50TCY
		ConvertADC(); 				// Start conversion
		while(BusyADC()); 			// Wait for completion
		result2 = ReadADC(); 		// Read result
		Delay10TCYx(10000);

		//calculate voltage for the current number
		CTvoltage  = ((result2 * 4.8)/1024);
		currentRatio = (CTvoltage/3.2) + .15;

		current = currentRatio;

		if (current <=0.25 ) {
			SetDDRamAddr(0x09);
			putrsXLCD("0.00");
		}
		else {
			result2 = current;
			data = itoa(result2, data); 
			SetDDRamAddr(0x09);		
			putsXLCD(data);
			putrsXLCD(".");
			result2A = (current - result2)*1000;
			data = itoa(result2A, data);
			
			if(result2A <100){
				result2A = (current - result2)*100;
				data = itoa(result2A, data);
				putrsXLCD("0");
				putsXLCD(data);
			}
			else{
				putsXLCD(data);
			}
		}

		//check over current condition.  if greater than system shutdown
		if (current >= 1.2) {
			PORTDbits.RD1 = 1;
			Delay1KTCYx(5000);
			PORTDbits.RD1 = 0;
		}
		
		Delay1KTCYx(1000);

	}

		//Clears the screen
		SetDDRamAddr(0x00);
		putrsXLCD("                ");
		SetDDRamAddr(0x40);
		putrsXLCD("                ");


//-----------------------------------------------------------------------
//Calculate and display the Power and kWh values to the LCD
//-----------------------------------------------------------------------
		
	for(i = 1; i<30; i++){

		USART();

		//Relay status if RD2 is high then relay is open, else closed.
		if (PORTDbits.RD2 == 1) { 
			reg[0] = 1;
			SetDDRamAddr(0x47);
			putrsXLCD("Open  ");
		}
		else {
			reg[0] = 0;
			SetDDRamAddr(0x47);
			putrsXLCD("Closed");
		}

		SetDDRamAddr(0x00);
		putrsXLCD("Power:");
		SetDDRamAddr(0x40);
		putrsXLCD("Relay:");


/*
		//Read in Data
		SetChanADC(ADC_CH0);
		Delay10TCYx(100); 			// Delay for 50TCY
		ConvertADC(); 				// Start conversion
		while(BusyADC()); 			// Wait for completion
		result1 = ReadADC(); 		// Read result
		Delay10TCYx(100); 
*/
		SetChanADC(ADC_CH1);
		Delay10TCYx(800); 			// Delay for 50TCY
		ConvertADC(); 				// Start conversion
		while(BusyADC()); 			// Wait for completion
		result2 = ReadADC(); 		// Read result
		Delay10TCYx(10500);
		CTvoltage  = ((result2 * 4.8)/1024);

		currentRatio = (CTvoltage/3.2) + .15;

		current = currentRatio;				

		power = 117.0 * current;

		powerScale = power * 1000;
		reg[6] = powerScale;		
		
		if (current <=.25 ) {
			SetDDRamAddr(0x08);
			putrsXLCD("0.00");
		}
		else {

			result1 = power;
			data = itoa(result1, data); 
			SetDDRamAddr(0x07);	
			putsXLCD(data);
			putrsXLCD(".");
			result1A = (power - result1)*1000;
			data = itoa(result1A, data);
		

			if(result1A <100){
				result1A = (power - result1)*100;
				data = itoa(result1A, data);
				putrsXLCD("0");
				putsXLCD(data);
			}
			else{
				putsXLCD(data);
			}
		}
		if (current >= 1.2) {	
			PORTDbits.RD1 = 1;
			Delay1KTCYx(5000);
			PORTDbits.RD1 = 0;
		}

		Delay1KTCYx(1000);
	}



		SetDDRamAddr(0x00);
		putrsXLCD("                ");
		SetDDRamAddr(0x40);
		putrsXLCD("                ");

	}

}


void USART(void)
{
	while(DataRdyUSART())
	{
		char x = getcUSART();
		if (x == 55)
		{
			intCurrent = current * 1000;
			currentIntString = itoa(intCurrent,currentIntString);
			putsUSART(currentIntString);
			putrsUSART("-");


			//check relay status			
			if(PORTDbits.RD2 == 1)
				putrsUSART("1");
			else
				putrsUSART("0");
			
			//sprintf(relayString, "%#010x", reg[0]);
			//putsUSART(relayString);
			putrsUSART("?");
		}
		//check relay control
		if(x == 0)
		{
			PORTDbits.RD0 = 1;
			Delay1KTCYx(5000);
			PORTDbits.RD0 = 0;
		}
		if(x == 1)
		{
			PORTDbits.RD1 = 1;
			Delay1KTCYx(5000);
			PORTDbits.RD1 = 0;
		}
	}
}



void DelayFor18TCY( void )
{
Nop(); Nop(); Nop(); Nop();
Nop(); Nop(); Nop(); Nop();
Nop(); Nop(); Nop(); Nop();
Nop(); Nop();
}

void DelayPORXLCD( void )
{
Delay1KTCYx(15); //Delay of 15ms
return;
}

void DelayXLCD( void )
{
Delay1KTCYx(5); //Delay of 5ms
return;
}


/*
		//Read in Data
		SetChanADC(ADC_CH0);		//Set channal to ADC0
		Delay10TCYx(100); 			// Delay for 50TCY
		ConvertADC(); 				// Start conversion
		while(BusyADC()); 			// Wait for completion
		result1 = ReadADC(); 		// Read result
		Delay10TCYx(100); 

		voltage  = (result1* 4.99)/1023;	//Calculate real voltage value from ADC value
		result1 = voltage;
		data = itoa(result1, data); 
		SetDDRamAddr(0x08);	
		putsXLCD(data);
		putrsXLCD(".");
		result1A = (voltage - result1)*1000;
		data = itoa(result1A, data);
		if(result1A <100){
			result1A = (voltage - result1)*100;
			data = itoa(result1A, data);
			putrsXLCD("0");
			putsXLCD(data);
		}
		else{putsXLCD(data);
		}		
*/
	


